<script lang="ts" setup>
import {
  addCommentApi,
  addReplyApi,
  getCommentApi,
  getReplyApi,
  handleDeleteApi,
  handleDeleteReplyApi,
  handleDislikeApi,
  handleLikedApi
} from "@/api/detail";
import {ref} from "vue";
import type {CommentItem, ReplyItem} from "@/types/comment";
import {useUserStore} from "@/stores/user";
import {CommentSortType, CommentType} from "@/enum/comment";
import {IMessage} from "@/components/aw-message/message";
import type {AnimalDetailItem} from "@/types/animals";

const props = withDefaults(defineProps<{
  animalId: number
  animals?: AnimalDetailItem
  showInput?: boolean
}>(), {
  showInput: true
})

const userStore = useUserStore()
const commentList = ref<CommentItem[]>() // 评论数据列表
const replyList = ref<ReplyItem[]>() // 评论回复列表
const isLoading = ref(false) // 是否正在加载
const isNoData = ref(false) // 是否没有更多数据
const delayLoading = ref(false) //评论节流
const emit = defineEmits<{
  update: [],
  mask: [],
  share: [comment: CommentItem] //提交分享事件
  noData: [] // 没有评论时触发
}>()
/**
 * 获取评论列表数据
 * @param data
 */
const getComment = async (data: {
  page: number,
  pageSize: number,
  animalId: number,
  sortType?: CommentSortType,
  loadMore?: boolean,
}) => {
  if (isNoData.value && data.loadMore) {
    return
  }
  if (delayLoading.value) {
    return
  }
  delayLoading.value = true
  const res = await getCommentApi(data)
  if (res.code !== '1') {
    return uni.showToast({
      title: res.message || '系统繁忙，请稍后重试',
      icon: 'none'
    })
  }
  if (res.data.pageSize * res.data.page >= res.data.total) {
    isNoData.value = true
    emit('noData')
  }
  if (data.loadMore) {
    commentList.value = commentList.value?.concat(res.data.data)
  } else {
    commentList.value = res.data.data
  }
  isLoading.value = true
  delayLoading.value = false
}

const delaySort = ref(false)
/**
 * 当评论排序发生改变时触发
 * @param sortType 0——点赞 1——时间
 */
const onChangeSort = async (sortType: 0 | 1) => {
  if (delaySort.value) {
    return
  }
  delaySort.value = true
  uni.showLoading({title: '加载中...'})
  await getComment({page: 1, pageSize: 10, animalId: props.animalId, sortType: sortType})
  uni.hideLoading()
  delaySort.value = false
}

const comment = ref()
const popupToLogin = ref()
const onClickInput = () => {
  // 判断是否登录
  if (!userStore.userInfoData) {
    const platform = uni.getSystemInfoSync().uniPlatform
    if (platform === 'app' || platform === 'web') {
      IMessage({
        content: '请先登录',
        type: 'error',
        showIcon: true,
      })
    } else {
      uni.showToast({title: '请先登录', icon: 'none'})
    }
    popupToLogin.value.open()
    return
  }
  comment.value.commentPopup.open()
}
const gotoLogin = () => {
  uni.navigateTo({url: '/subPkg/login/login'})
}
/**
 * 点击发布评论时触发
 * @param type 评论类型
 * @param content 用户评论内容
 */
const onSendComment = async (content: string) => {
  uni.showLoading({title: '发布中...'})
  // 发送请求
  const res = await addCommentApi({
    animalId: props.animalId,
    content: content,
    userName: userStore.userInfoData!.username,
    userAvatar: userStore.userInfoData!.avatarURL
  })
  uni.hideLoading()
  if (res.code !== '1') {
    return uni.showToast({title: '服务器繁忙，请稍后重试', icon: 'none'})
  }
  uni.showToast({title: '评论成功', icon: 'none'})
  uni.hideKeyboard()
  await getComment({page: 1, pageSize: 50, animalId: props.animalId})
  comment.value.commentPopup.close()
  emit('update')
}

const delayReply = ref(false)
/**
 * 获取单个评论的回复列表（不支持点踩和分享）
 * @param commentId 父级评论id
 */
const onClickTotalReply = async (commentId: number) => {
  if (delayReply.value) {
    return
  }
  delayReply.value = true
  // 根据commentId找到对应的评论回复
  const res = await getReplyApi(commentId)
  replyList.value = res.data
  delayReply.value = false
  // 打开评论回复弹层
  comment.value.openReplyPopup()
}

const delayLike = ref(false)
const delayDislike = ref(false)
/**
 *  点赞评论
 *  @param data 点赞的评论数据
 *  commentId 评论id
 *   type 点赞的评论类型
 */
const handleLike = async (data: { type: CommentType, index: number }) => {
  // 判断是否登录
  if (!userStore.userInfoData) {
    const platform = uni.getSystemInfoSync().uniPlatform
    if (platform === 'app' || platform === 'web') {
      return IMessage({
        content: '请先登录',
        type: 'error',
        showIcon: true,
      })
    } else {
      return uni.showToast({title: '请先登录', icon: 'none'})
    }
  }
  // 此处建议节流
  if (delayLike.value) {
    return
  }
  delayLike.value = true
  let commentId: number
  let likedUserId: number // 被点赞的用户id
  let status: 0 | 1 = 0
  const type = data.type
  if (data.type === CommentType.COMMENT) {
    // 评论
    status = commentList.value![data.index].liked ? 0 : 1
    commentId = commentList.value![data.index].commentId
    likedUserId = commentList.value![data.index].userId
  } else {
    // 回复
    status = replyList.value![data.index].liked ? 0 : 1
    commentId = replyList.value![data.index].replyId
    likedUserId = replyList.value![data.index].userReplyId
  }
  const res = await handleLikedApi({commentId, type, status, likedUserId})
  if (status === 1) {
    uni.showToast({title: '点赞成功', icon: 'none'})
  }
  delayLike.value = false
  if (res.code !== '1') {
    return uni.showToast({title: '服务器繁忙，请稍后重试', icon: 'none'})
  }
  // 修改点赞状态
  if (data.type === CommentType.COMMENT) {
    commentList.value![data.index].liked = !commentList.value![data.index].liked
    if (commentList.value![data.index].disliked) {
      commentList.value![data.index].disliked = false
    }
    status === 1 ? commentList.value![data.index].likes++ : commentList.value![data.index].likes--
  } else {
    replyList.value![data.index].liked = !replyList.value![data.index].liked
    status === 1 ? replyList.value![data.index].likes++ : replyList.value![data.index].likes--
  }
}

/**
 *  处理点踩
 * @param index 评论索引（回复没有点踩功能）
 */
const handleDislike = async (index: number) => {
  if (!userStore.userInfoData) {
    const platform = uni.getSystemInfoSync().uniPlatform
    if (platform === 'app' || platform === 'web') {
      return IMessage({
        content: '请先登录',
        type: 'error',
        showIcon: true,
      })
    } else {
      return uni.showToast({title: '请先登录', icon: 'none'})
    }
  }
  if (delayDislike.value) {
    return
  }
  delayDislike.value = true
  const status: 0 | 1 = commentList.value![index].disliked ? 0 : 1
  const commentId: number = commentList.value![index].commentId
  const userId = commentList.value![index].userId
  // 发起请求
  const res = await handleDislikeApi(commentId, status, userId)
  if (res.code !== '1') {
    delayDislike.value = false
    return uni.showToast({title: res.message || '服务器繁忙，请稍后重试', icon: 'none'})
  }
  // 修改点踩状态
  commentList.value![index].disliked = !commentList.value![index].disliked
  if (commentList.value![index].liked && status === 1) { // 在点踩之前已经点过赞，并且点踩状态为点踩，则次数-1
    commentList.value![index].liked = false
    commentList.value![index].likes--
  }
  delayDislike.value = false
}

/**
 * 回复时触发(注意这里并不是点击发送回复，而是点击回复)
 * @param type 该评论类型
 * @param index 评论索引
 */
const handleReply = (type: CommentType, index: number) => {
}

/**
 * 发送回复时触发
 * @param replyDetail
 */
const onSendReply = async (replyDetail: {
  content: string,
  commentId: number,
  toUserId: number,
  toUserName: string,
  type: 0 | 1,
  originId: number
}) => {
  await uni.showLoading({title: '发布中...'})
  // 发送请求
  const res = await addReplyApi({
    animalId: props.animalId,
    content: replyDetail.content,
    userReplyName: userStore.userInfoData!.username,
    userReplyAvatar: userStore.userInfoData!.avatarURL,
    toUserName: replyDetail.toUserName,
    toUserId: replyDetail.toUserId,
    commentId: replyDetail.commentId,
    type: replyDetail.type,
    originId: replyDetail.originId
  })
  uni.hideLoading()
  if (res.code !== '1') {
    return uni.showToast({title: '服务器繁忙，请稍后重试', icon: 'none'})
  } else {
    uni.showToast({title: '回复成功', icon: 'none'})
  }
  uni.hideKeyboard()
  comment.value.commentPopup.close()
  // 重新请求该评论的回复列表
  const resReply = await getReplyApi(replyDetail.commentId)
  replyList.value = resReply.data
  await getComment({page: 1, pageSize: 10, animalId: props.animalId, sortType: CommentSortType.LIKES})
}

/**
 * 删除评论
 * @param commentId 评论id
 */
const onDeleteComment = async (commentId: number) => {
  const res = await handleDeleteApi(commentId)
  if (res.code !== '1') {
    return uni.showToast({title: res.message || '服务器繁忙，请稍后重试', icon: 'none'})
  }
  uni.showToast({title: '删除成功', icon: 'none'})
  await getComment({page: 1, pageSize: 50, animalId: props.animalId})
  emit('update')
}
/**
 * 删除评论
 * @param replyId
 */
const onDeleteReply = async (replyId: number) => {
  const res = await handleDeleteReplyApi(replyId)
  if (res.code !== '1') {
    return uni.showToast({title: res.message || '服务器繁忙，请稍后重试', icon: 'none'})
  }
  uni.showToast({title: '删除成功', icon: 'none'})
  comment.value.onCloseReplyPopup()
  await getComment({page: 1, pageSize: 50, animalId: props.animalId})
  emit('update')
}

/**
 * 举报评论
 * @param commentId 被举报评论id
 */
const onReport = async (commentId: number) => {
  // const res = await handleReportApi(commentId)
  // if (res.code !== '1') {
  //   return uni.showToast({title: res.message || '服务器繁忙，请稍后重试', icon: 'none'})
  // }
  uni.showToast({title: '举报成功', icon: 'none'})
}

/**
 * 分享评论
 * @param comment
 */
const shareComment = ref<CommentItem>()

const handleShare = (comment: CommentItem) => {
  const platform = uni.getSystemInfoSync().uniPlatform
  if (platform === 'web') { // h5端不需要生成图片就不需要提交事件
    uni.setClipboardData({
      data: comment.userName + '：' + comment.content + '\n' + '更多热评点击——www.cuteworld.top (≧∇≦)ﾉ',
      success: () => {
        uni.showToast({title: '已复制该评论', icon: 'none'})
      }
    })
  } else {
    emit('share', comment)
  }
}
// 暴露给父级，让父级发起初始请求
defineExpose<{
  getComment: typeof getComment
}>({
  getComment,
})

</script>

<template>
  <view>
    <view v-if="!isLoading">
      <aw-loader></aw-loader>
    </view>
    <view v-else>
      <aw-comment ref="comment" :comment-list="commentList" :no-more="isNoData" :reply-list="replyList"
                  :show-comment-input="showInput"
                  :user-id="userStore.userInfoData?.userID.toString()"
                  @clickInput="onClickInput"
                  @clickReply="handleReply"
                  @clickTotalReply="onClickTotalReply"
                  @delete="onDeleteComment"
                  @deleteReply="onDeleteReply"
                  @dislike="handleDislike"
                  @like="handleLike"
                  @report="onReport"
                  @sendComment="onSendComment"
                  @sendReply="onSendReply"
                  @share="handleShare"
                  @sort="onChangeSort">
      </aw-comment>
    </view>

  </view>
  <uni-popup ref="popupToLogin" type="dialog">
    <uni-popup-dialog confirm-text="前往登录" content="是否前往登录？" title="提示" type="info"
                      @confirm="gotoLogin"></uni-popup-dialog>
  </uni-popup>
</template>

<style lang="scss" scoped></style>